package cn.dslcode.security.config.security;

import cn.dslcode.common.core.string.StringUtil;
import cn.dslcode.security.common.CaptchaAuthenticationException;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.RememberMeServices;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author dongsilin
 * @version 2018/4/8.
 *          图片验证码Filter
 */
@Slf4j
@Data
public final class CustomCaptchaVerifyFilter extends UsernamePasswordAuthenticationFilter {

    /**
     * 验证码字段名称
     */
    private String captchaCodeParameterName;

    /**
     * 建立构造器，排除循环依赖
     * @param authenticationManager
     * @param successHandler
     * @param failureHandler
     */
    public CustomCaptchaVerifyFilter(AuthenticationManager authenticationManager, AuthenticationSuccessHandler successHandler, AuthenticationFailureHandler failureHandler, String loginFormUri, String captchaCodeParameterName) {
        AntPathRequestMatcher requestMatcher = new AntPathRequestMatcher(loginFormUri, RequestMethod.POST.name());
        setRequiresAuthenticationRequestMatcher(requestMatcher);
        setAuthenticationManager(authenticationManager);
        setAuthenticationSuccessHandler(successHandler);
        setAuthenticationFailureHandler(failureHandler);
        this.captchaCodeParameterName = captchaCodeParameterName;
    }

    /**
     * 建立构造器，排除循环依赖
     * @param authenticationManager
     * @param rememberMeServices
     * @param successHandler
     * @param failureHandler
     */
    public CustomCaptchaVerifyFilter(AuthenticationManager authenticationManager, RememberMeServices rememberMeServices, AuthenticationSuccessHandler successHandler, AuthenticationFailureHandler failureHandler, String loginFormUri, String captchaCodeParameterName) {
        this(authenticationManager, successHandler, failureHandler, loginFormUri, captchaCodeParameterName);
        setRememberMeServices(rememberMeServices);
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        String captchaCode = request.getParameter(this.captchaCodeParameterName);
        if (StringUtil.isEmpty(captchaCode)) {
            throw new CaptchaAuthenticationException("验证码不能为空");
        }
        if (StringUtil.ne(captchaCode, "1234")) {
            throw new CaptchaAuthenticationException("验证码错误");
        }
        return super.attemptAuthentication(request, response);
    }

}